/*
 * Copyright (c) 2020, chao
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-08-20     chao         the first version
 */

#include <rtthread.h>
#include <stdlib.h>
#include "xpt2046_calibration.h"
#include "lcd_port.h"

static xpt_cal_t xpt = RT_NULL;

/**
  * @brief  xpt2046触摸ic校验初始化
  * @param  
  * @retval 
  */
int xpt2046_calibration_init(void)
{
    uint16_t logX; //logX为逻辑点1到逻辑点0的水平距离或者逻辑点3到逻辑点2的水平距离
    uint16_t logY; //logY为逻辑点2到逻辑点0的垂直距离或者逻辑点3到逻辑点1的垂直距离
    uint16_t phyX1;//phyX1为物理点1到物理点0的水平距离
    uint16_t phyX2;//phyX2为物理点3到物理点2的水平距离
    uint16_t phyY1;//phyY1为物理点2到物理点0的垂直距离
    uint16_t phyY2;//phyY2为物理点3到物理点1的垂直距离
        
    xpt = (xpt_cal_t)rt_calloc(1, sizeof(struct xpt_cal));
    if (xpt == RT_NULL) return -RT_ENOMEM;

    xpt->log_point[0].x = 20;
    xpt->log_point[0].y = 20;
    xpt->log_point[1].x = LCD_WIDTH - 20;
    xpt->log_point[1].y = 20;
    xpt->log_point[2].x = 20;
    xpt->log_point[2].y = LCD_HEIGHT - 20;
    xpt->log_point[3].x = LCD_WIDTH - 20;
    xpt->log_point[3].y = LCD_HEIGHT - 20;
    xpt->log_center.x = LCD_WIDTH / 2;
    xpt->log_center.y = LCD_HEIGHT / 2;

    xpt->phy_point[0].x = 575;
    xpt->phy_point[0].y = 498;
    xpt->phy_point[1].x = 3680;
    xpt->phy_point[1].y = 498;
    xpt->phy_point[2].x = 578;
    xpt->phy_point[2].y = 3779;
    xpt->phy_point[3].x = 3726;
    xpt->phy_point[3].y = 3795;
    xpt->phy_center.x   = 2130;
    xpt->phy_center.y   = 2143;

    logX = abs(xpt->log_point[1].x - xpt->log_point[0].x);
    logY = abs(xpt->log_point[2].y - xpt->log_point[0].y);
    
    phyX1 = abs(xpt->phy_point[1].x - xpt->phy_point[0].x);
    phyX2 = abs(xpt->phy_point[3].x - xpt->phy_point[2].x);
    phyY1 = abs(xpt->phy_point[2].y - xpt->phy_point[0].y);
    phyY2 = abs(xpt->phy_point[3].y - xpt->phy_point[1].y);    
    
    xpt->kx = ((float)(phyX1+phyX2)/2/logX);
    xpt->ky = ((float)(phyY1+phyY2)/2/logY);

    //xpt->kx = 15.612500;
    //xpt->ky = 11.751785;

    rt_kprintf("xpt2046 calibration init success.\n");
    //rt_kprintf("kx = %d, ky = %d\n", xpt->kx, xpt->ky);

    return RT_EOK;
}

/**
  * @brief  根据计算公式logX = (phyX - phyCenterX)/kx + logCenterX
  *         通过输入逻辑x计算出物理x
  * @param  
  * @retval 
  */
uint16_t xpt_caculate_phy_x(uint16_t logX)
{
    if (xpt == RT_NULL) return 0;
    return (uint16_t)((float)(logX - xpt->log_center.x) * xpt->kx + xpt->phy_center.x);
}

/**
  * @brief  根据计算公式logY = (phyY - phyCenterY)/ky + logCenterY
  *         通过输入逻辑y计算出物理y
  * @param  
  * @retval 
  */
uint16_t xpt_caculate_phy_y(uint16_t logY)
{
    if (xpt == RT_NULL) return 0;
    return (uint16_t)((float)(logY - xpt->log_center.y) * xpt->ky + xpt->phy_center.y);
}

/**
  * @brief  根据计算公式logX = (phyX - phyCenterX)/kx + logCenterX
  *         通过输入物理x计算出逻辑x
  * @param  
  * @retval 
  */
uint16_t xpt_caculate_log_x(uint16_t phyX)
{
    if (xpt == RT_NULL) return 0;
    return (uint16_t)((float)(phyX - xpt->phy_center.x) / xpt->kx + xpt->log_center.x);
}

/**
  * @brief  根据计算公式logY = (phyY - phyCenterY)/ky + logCenterY
  *         通过输入物理y计算出逻辑y
  * @param  
  * @retval 
  */
uint16_t xpt_caculate_log_y(uint16_t phyY)
{
    if (xpt == RT_NULL) return 0;
    return (uint16_t)((float)(phyY - xpt->phy_center.y) / xpt->ky + xpt->log_center.y);
}



